#include"star.h"
#include<Windows.h>
#include<stdlib.h>
#include<conio.h>
#include<algorithm>

#pragma once
using namespace std;
extern int Round = 20;//总回合数
extern int now_round = 0;//当前回合数



void clear(short x, short y, short w, short h) //清理指定矩形区域(从(x,y)到(x+w,y+h)的矩形
{
	for (int i = 0; i < h; i++) {
		gotoxy(x, y + i);
		for (int j = 0; j < w; j++) putchar(' ');
	}
}
static void SetOrder() {

	for (int i = 0; i < 4; i++) {
		order[i].second = player[i].character_id;

		int ans = chara[order[i].second+1]->Roll();
		order[i].first = ans;
	}
	sort(order + 1, order + 5);
	reverse(order + 1, order + 5);

}
static void ActsLog(string s, short x, short y) {
	gotoxy(x, y);
	cout << s;
}

static void ChooseLoot(int player_id) {
	pair<string, short> p[20];//前值表示道具名 后值表示所在行
	int len = 0;
	if (player[player_id].loots[0] == NULL)return;
	for (int j = 0; j <= 20 && player[player_id].loots[j] != NULL; j++) {
		Loot* l = player[player_id].loots[j];
		ActsLog(l->loot_name, x, y + j + 1);//在行动框显示
		p[j].first = l->loot_name;
		p[j].second = y + j + 1;
		len++;
	}
	p[++len] = { "不使用道具",y + len + 1 };
	for (int j = 0; j <= len; j++) {//循环打印
		gotoxy(x, p[j].second);
		cout << j + 1 << "." << p[j].first;
	}

	//选择
	short line_next = y; int temp = 0;
	short line_now = y;
	while (true) {//光标移动
		int k = _kbhit();//判断键盘是否有输入
		if (k) {//如果有敲击返回1
			char c = (char)_getch();
			if ('s' == c && temp < len) {
				MoveCursor({ x,line_now }, { x,line_next += 2 }, p[temp++].first, p[temp].first, 15, 31);
				line_now += 2;
			}
			else if ('w' == c && temp > 0) {
				MoveCursor({ x,line_now }, { x,line_next -= 2 }, p[temp--].first, p[temp].first, 15, 31);
				line_now -= 2;
			}
			else if ('\n' == c) {
				if (temp == len)return;
				if (player[player_id].loots[temp]->loot_time == 1) {
					player[player_id].loots[temp]->LootFun(player_id);//如果是立即生效的就调用生效函数
					return;
				}
				else {//否则加入生效队列
					for (int j = 0; j <= 20; j++) {
						if (player[player_id].loot_queue[j] == NULL) {
							player[player_id].loot_queue[j] = player[player_id].loots[temp];
							return;
						}
					}

				}
			}
		}
	}
}

static int RollInRound(int player_id) {
	gotoxy(x, y);
	cout << "请按空格键进行投点";
	while (1) {
		int k = _kbhit();//判断键盘是否有输入
		if (k) {//如果有敲击返回1
			char c = (char)_getch();
			if ('\n' == c) {
				int chara_id = player[player_id].character_id;
				int res = chara[chara_id]->Roll();
				gotoxy(x, y);
				cout << "你投出的点数为：" << res;
				return res;
			}
		}
	}
}

static void CheckEvent(int player_id_now) {
	if (mp[player[player_id_now].mp_locat]->event_id != NULL) {//判断落点事件
		if (mp[player[player_id_now].mp_locat]->event_id->Check(now_round)) {
			if (mp[player[player_id_now].mp_locat]->event_id->event_time == 1) {//判断是否立即生效
				mp[player[player_id_now].mp_locat]->event_id->EventFun(player_id_now);
			}
			else {
				for (int i = 0; i <= 20; i++) {//放入全局事件队列
					if (event_queue[i] == NULL) {
						event_queue[i] = mp[player[player_id_now].mp_locat]->event_id;
						return;
					}
				}
			}
		}
	}
}
void :: GamePlay() {
	CreatStar();
	SetOrder();
	gotoxy(x, y);
	printf("行动顺序为：1.玩家%d 2.玩家%d 3.玩家%d 4.玩家%d", order[1].first, order[2].first, order[3].first, order[4].first);
	//加入全局事件
	int i = 0;
	while (i++) {
		i %= 4;//0，1，2，3
		if (i == 0)now_round++;
		int player_id_now = order[i + 1].first;
		for (int j = 0; j <= 20 && event_queue[j] != NULL; j++) {//扫描全局事件队列
			Event* e = event_queue[j];
			if (e->event_time == 2) {
				e->EventFun(player_id_now);
			}
			event_queue[j] = NULL;

		}
		for (int j = 0; j <= 10 && player[player_id_now].event_queue[j] != NULL; j++) {//扫描当前玩家事件队列
			Event* e = player[player_id_now].event_queue[j];
			if (e->event_time == 2) {
				e->EventFun(player_id_now);
			}
			player[player_id_now].event_queue[j] = NULL;

		}
		for (int j = 0; j <= 10 && player[player_id_now].loot_queue[j] != NULL; j++) {//扫描当前玩家道具队列
			Loot* l = player[player_id_now].loot_queue[j];
			if (l->loot_time == 2) {
				l->LootFun(player_id_now);
			}
			player[player_id_now].loot_queue[j] = NULL;
		}
		ChooseLoot(player_id_now);//选择道具
		PlayerState();//维护道具栏
		clear(x, y, 23, 13);//清除行动栏
		int step = RollInRound(player_id_now);
		bool direct;//方向判断
		if (step >= 0)
		{ direct = 1; }
		else
		{ direct = 0; }
		while (step--) {//走一步判断一次
			MapMove(player[player_id_now].mp_locat,direct);
			if (mp[player[player_id_now].mp_locat]->star) {//判断星星
				player[player_id_now].star_num++;
				mp[player[player_id_now].mp_locat]->star = false;
				CreatStar();
			}
			if (player[player_id_now].mp_locat == 0) {//判断起点
				player[player_id_now].star_num++;
			}
		}
		CheckEvent(player_id_now);
		Rank();
		if (now_round == Round)break;//如果是最后一回合就弹出
	}
	clear(x, y, 23, 13);//清除行动栏
	gotoxy(x, y);
	cout << "游戏结束！";
	ShowRankPage(1);
}